﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using NBearLite;
using Xin478.CSWork.Common;
using Xin478.CSWork.DomainModel;
using Xin478.MySocket;


namespace Xin478.CSWork.Server
{
    public partial class Form1 : Form, IServer
    {
        #region 字段
        TcpServer server;
        static readonly object lockHelper = new object();

        TransferFileHelper transferFileHelper;
        OnlineUser onlineUser;
        #endregion

        Hashtable filterTable;

        public Form1()
        {
            InitializeComponent();
            filterTable = new Hashtable();
            Assembly assembly = System.Reflection.Assembly.GetAssembly(this.GetType());
            Type[] types = assembly.GetTypes();
            foreach (Type type in types)
            {
                if ( type.IsClass && !type.IsAbstract && type.IsPublic)
                {
                    Type t = type.GetInterface("IResponse");
                    if (t != null && !filterTable.ContainsKey(type.Name))
                    {
                        IResponse ir = Activator.CreateInstance(type) as IResponse;
                        ir.StartFilter(this);
                        filterTable[type.Name] = ir;
                    }
                }
            }
            this.Load += new EventHandler(Form1_Load);
        }

        void InitWorkDir()
        {
            string fileDataDir;
            string sendPicDir;
            if (AppSetting.Default.文件保存目录.IndexOf(':') >= 0) fileDataDir = AppSetting.Default.文件保存目录;
            else fileDataDir = Application.StartupPath + "\\" + AppSetting.Default.文件保存目录;

            if (AppSetting.Default.图片保存目录.IndexOf(':') >= 0) sendPicDir = AppSetting.Default.图片保存目录;
            else sendPicDir = Application.StartupPath + "\\" + AppSetting.Default.图片保存目录;

            fileDataDir = fileDataDir.Replace("/", "\\");
            sendPicDir = sendPicDir.Replace("/", "\\");
            if (!fileDataDir.EndsWith("\\")) fileDataDir += "\\";
            if (!sendPicDir.EndsWith("\\")) sendPicDir += "\\";


            AppSetting.Default["图片保存目录"] = sendPicDir;
            AppSetting.Default["文件保存目录"] = fileDataDir;

            if (!Directory.Exists(fileDataDir))
            {
                try
                {
                    DirectoryInfo dirInfo = Directory.CreateDirectory(fileDataDir);
                }
                catch
                {
                    MessageBox.Show("初始化文件保存目录失败");
                    this.Close();
                    Application.Exit();
                    return;
                }
            }

            if (!Directory.Exists(sendPicDir))
            {
                try
                {
                    DirectoryInfo dirInfo = Directory.CreateDirectory(sendPicDir);
                }
                catch
                {
                    MessageBox.Show("初始化图片保存目录失败");
                    this.Close();
                    Application.Exit();
                    return;
                }
            }
        }

        void Form1_Load(object sender, EventArgs e)
        {
            InitWorkDir();

            this.任务栏图标.MouseDoubleClick += new MouseEventHandler(任务栏图标右击事件);
            this.onlineUser = new OnlineUser();
            this.onlineUser.DeletedOnlineUser += new OnlineUser.OnlineUserHandler(onlineUser_DeletedOnlineUser);
            this.onlineUser.AddedOnlineUser += new OnlineUser.AddOnlineUserHandler(onlineUser_AddedOnlineUser);
            server = new TcpServer(AppSetting.Default.服务器IP, AppSetting.Default.监听端口, AppSetting.Default.最大连接数);

            server.DatagramAnalyze = new DatagramWorker();
            server.OnReceivedDatagramEvent += new NetEventHandler(服务端接收处理);
            server.OnClientConnectEvent += new NetEventHandler(delegate(object _sender, NetEventArgs _e) { WinForm.DoThreadSafe(this.textBox1, delegate() { this.textBox1.AppendText(DateTime.Now.ToString()+_e.Client.ToString() + "连线");}); });
            server.OnClientCloseEvent += new NetEventHandler(delegate(object _sender, NetEventArgs _e) { 
                WinForm.DoThreadSafe(this.textBox1, delegate() {this.textBox1.AppendText(DateTime.Now.ToString() + _e.Client.ToString() + "断开");});
                onlineUser.Delete(_e.Client);
            });
            this.transferFileHelper = new TransferFileHelper();
            this.transferFileHelper.MaxWorkingNum = 10;
            this.transferFileHelper.sendInvoke = server.Send;
            this.transferFileHelper.AddingTransferHandler += new TransferFileHelper.TransferCancelHandler(transferFileHelper_AddingTransferHandler);
            this.DatagramReceived += new DatagramReceiveHandler(this.transferFileHelper.DatagramReceive);
            
            this.启动服务();
        }

        void onlineUser_AddedOnlineUser(Session session, EmployeeInfo employeeInfo)
        {
            WinForm.DoThreadSafe(this.在线人员列表框, delegate() { this.在线人员列表框.Items.Add(session.ID.ID + ":" + employeeInfo.Name); });
        }

        void onlineUser_DeletedOnlineUser(int sessionId, int userId)
        {
            SessionId sId = new SessionId(sessionId);
            object obj = null;
            lock (lockHelper)
            {
                obj = server.SessionTable[sId];
            }
            if (obj != null)
            {
                this.Send(obj as Session, "用户踢出");
            }
            for (int i = 0; i < this.在线人员列表框.Items.Count; i++)
            {
                if (this.在线人员列表框.Items[i].ToString().IndexOf(sessionId + ":") == 0)
                    WinForm.DoThreadSafe(this.在线人员列表框, delegate() { this.在线人员列表框.Items.RemoveAt(i); });
            }
        }

        void transferFileHelper_AddingTransferHandler(TransferFileInfo transferFileInfo, ref bool canceled)
        {
            if (transferFileInfo.Status == TransferFileStatus.DownLoad)
            {
                string tag = transferFileInfo.Tag.ToString();
                if (string.Compare(tag, "cmd") == 0)
                {
                    transferFileInfo.TempFileDir = AppSetting.Default["图片保存目录"].ToString();
                    transferFileInfo.ToFileName = transferFileInfo.MD5 + transferFileInfo.FileExt;
                    if (File.Exists(transferFileInfo.TempFileDir + transferFileInfo.ToFileName))
                    {
                        canceled = true;
                        return;
                    }
                }
                else if (tag.StartsWith("att?"))
                {
                    int i = tag.IndexOf("?")+1;
                    int j = tag.LastIndexOf("?");
                    transferFileInfo.TempFileDir = AppSetting.Default["文件保存目录"].ToString() + tag.Substring(j+1) + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
                    transferFileInfo.FileName = tag.Substring(i, j - i)+ transferFileInfo.FileExt;
                }
                transferFileInfo.FileDir = transferFileInfo.TempFileDir;
            }
        }

        void 服务端接收处理(object sender, NetEventArgs e)
        {
            bool cancel = false;
            if (DatagramReceived != null)
            {
                foreach (DatagramReceiveHandler handler in DatagramReceived.GetInvocationList())
                {
                    try
                    {
                        handler.Invoke(e.Client, ref cancel);
                    }
                    catch { }
                    if (cancel) return;
                }
            }

            DatagramBuilder builder = DatagramBuilder.ToBuilder(e.Client.Datagram);
            builder.Params[0] = e;
            WinForm.DoThreadSafe(this, delegate() { this.textBox1.AppendText(builder.Name + "\n"); });
            if( builder.Name.IndexOf('.')!=-1)
            {
                string[] s = builder.Name.Split('.');
                if (this.filterTable.ContainsKey(s[0]))
                {
                    object obj = this.filterTable[s[0]];
                    MethodInfo mi = obj.GetType().GetMethod(s[1], BindingFlags.Public  | BindingFlags.IgnoreCase | BindingFlags.Instance);
                    if (mi != null)
                    {
                        try
                        {
                            mi.Invoke(obj, builder.Params);
                        }
                        catch { }
                    }
                }
            }
            else
            {
                if (CommandReceived != null)
                {
                    foreach (CommandReceiveHandler handler in CommandReceived.GetInvocationList())
                    {
                        try
                        {
                            handler.Invoke(builder, ref cancel);
                        }
                        catch { }
                        if (cancel) return;
                    }
                }
            }
        }

        void 启动服务()
        {
            if (this.server.IsRun) return ;
            try
            {
                server.Start();
                this.任务栏图标.Icon = Resource1.服务启动;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void 停止服务()
        {
            if (!this.server.IsRun) return;
            this.server.CloseAllClient();
            this.server.Stop();
            this.任务栏图标.Icon = Resource1.服务停止;
        }

        #region 按钮事件

        private void 任务栏图标右击事件(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (this.server.IsRun)
                {
                    this.启动菜单按钮.Enabled = false;
                    this.停止菜单按钮.Enabled = true;
                }
                else
                {
                    this.启动菜单按钮.Enabled = true; 
                    this.停止菜单按钮.Enabled = false;
                }
            }
        }

        private void 启动菜单按钮_Click(object sender, EventArgs e)
        {
            this.启动服务();
        }

        private void 停止菜单按钮_Click(object sender, EventArgs e)
        {
            this.停止服务();
        }

        private void 退出菜单按钮_Click(object sender, EventArgs e)
        {
            if (this.server.IsRun && MessageBox.Show( "你确定要退出吗?这将断开所有在线用户！", "",MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                this.server.CloseAllClient();
                this.server.Stop();
                this.任务栏图标.Dispose();
                this.Close();
                this.Dispose();
                Application.Exit();
            }
        }
        #endregion

        #region IServer 成员


        public event CommandReceiveHandler CommandReceived;
        public event DatagramReceiveHandler DatagramReceived;
        public OnlineUser OnlineUser
        {
            get { return this.onlineUser; }
        }
        public TransferFileHelper TransferFileHelper
        {
            get { return this.transferFileHelper; }
        }
        public void Send(Session session, string cmd, params object[] fparams)
        {
            server.Send(session, new DatagramBuilder(cmd, fparams).ToByte());
        }
        public void Send(NetEventArgs e, string cmd, params object[] fparams)
        {
            this.Send(e.Client, cmd, fparams);
        }

        #endregion
    }
}
